Mini Moka
Mini Moka is a fast, concurrent cache library for Rust. Mini Moka is a light edition of Moka.
Mini Moka provides cache implementations on top of hash maps. They support full concurrency of retrievals and a high expected concurrency for updates. Mini Moka also provides a non-thread-safe cache implementation for single thread applications.
All caches perform a best-effort bounding of a hash map using an entry replacement algorithm to determine which entries to evict when the capacity is exceeded.
Features
- Thread-safe, highly concurrent in-memory cache implementation.
- A cache can be bounded by one of the followings:
- The maximum number of entries.
- The total weighted size of entries. (Size aware eviction)
- Maintains near optimal hit ratio by using an entry replacement algorithms inspired
by Caffeine:
- Admission to a cache is controlled by the Least Frequently Used (LFU) policy.
- Eviction from a cache is controlled by the Least Recently Used (LRU) policy.
- More details and some benchmark results are available here.
- Supports expiration policies:
- Time to live
- Time to idle
Change Log
Table of Contents
- Features
- Change Log
- Usage
- Example: Synchronous Cache
- Avoiding to clone the value at
get
- Examples (Part 2)
- Minimum Supported Rust Versions
- Developing Mini Moka
- Credits
- License
Usage
Add this to your Cargo.toml
:
[]
= "0.10"
Example: Synchronous Cache
The thread-safe, synchronous caches are defined in the sync
module.
Cache entries are manually added using insert
method, and are stored in the cache
until either evicted or manually invalidated.
Here's an example of reading and updating a cache by using multiple threads:
// Use the synchronous cache.
use Cache;
use thread;
Avoiding to clone the value at get
For the concurrent cache (sync
cache), the return type of get
method is
Option<V>
instead of Option<&V>
, where V
is the value type. Every time get
is
called for an existing key, it creates a clone of the stored value V
and returns
it. This is because the Cache
allows concurrent updates from threads so a value
stored in the cache can be dropped or replaced at any time by any other thread. get
cannot return a reference &V
as it is impossible to guarantee the value outlives
the reference.
If you want to store values that will be expensive to clone, wrap them by
std::sync::Arc
before storing in a cache. Arc
is a thread-safe
reference-counted pointer and its clone()
method is cheap.
use Arc;
let key = ...
let large_value = vec!; // 2 MiB
// When insert, wrap the large_value by Arc.
cache.insert;
// get() will call Arc::clone() on the stored value, which is cheap.
cache.get;
Example: Size Aware Eviction
If different cache entries have different "weights" — e.g. each entry has
different memory footprints — you can specify a weigher
closure at the cache
creation time. The closure should return a weighted size (relative size) of an entry
in u32
, and the cache will evict entries when the total weighted size exceeds its
max_capacity
.
use TryInto;
use Cache;
Note that weighted sizes are not used when making eviction selections.
Example: Expiration Policies
Mini Moka supports the following expiration policies:
- Time to live: A cached entry will be expired after the specified duration past
from
insert
. - Time to idle: A cached entry will be expired after the specified duration past
from
get
orinsert
.
To set them, use the CacheBuilder
.
use Cache;
use Duration;
A note on expiration policies
The cache builders will panic if configured with either time_to_live
or time to idle
longer than 1000 years. This is done to protect against overflow when computing
key expiration.
Minimum Supported Rust Versions
Mini Moka's minimum supported Rust versions (MSRV) are the followings:
Feature | MSRV |
---|---|
default features | Rust 1.61.0 (May 19, 2022) |
It will keep a rolling MSRV policy of at least 6 months. If only the default features are enabled, MSRV will be updated conservatively. When using other features, MSRV might be updated more frequently, up to the latest stable. In both cases, increasing MSRV is not considered a semver-breaking change.
Developing Mini Moka
Running All Tests
To run all tests including doc tests on the README, use the following command:
$ RUSTFLAGS='--cfg skeptic --cfg trybuild' cargo test --all-features
Generating the Doc
$ cargo +nightly -Z unstable-options --config 'build.rustdocflags="--cfg docsrs"' \
doc --no-deps
Credits
Caffeine
Mini Moka's architecture is heavily inspired by the Caffeine library for Java. Thanks go to Ben Manes and all contributors of Caffeine.
License
Mini Moka is distributed under either of
- The MIT license
- The Apache License (Version 2.0)
at your option.
See LICENSE-MIT and LICENSE-APACHE for details.